package wait_notify;

import lombok.extern.slf4j.Slf4j;
import util.Sleeper;

/**
 * obj.wait()让进入object-monitor的线程到waitSet等待
 * obj.notify()在object上正在waitSet等待的线程中挑一个唤醒
 * obj.notifyAll()让object上正在waitSet等待的所有线程全部唤醒
 * 注意：被唤醒后的线程处于runnable状态，需要重新以非公平的方式竞争锁的使用(cas替换锁-monitor的owner)
 */
@Slf4j(topic = "c.TestWaitNotify")
public class TestWaitNotify {
    final static Object obj = new Object();

    public static void main(String[] args) {
        new Thread(()->{
            synchronized (obj){
                log.debug("执行");
                try {
                    obj.wait(); //让线程在obj上一直等待下去
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("其他代码");
            }
        },"t1").start();
        new Thread(()->{
            synchronized (obj){
                log.debug("执行");
                try {
                    obj.wait(); //让线程在obj上一直等待下去
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("其他代码");
            }
        },"t2").start();
        //主线程两秒后执行
        Sleeper.sleep(2);
        log.debug("唤醒等待在obj上的其他线程");
        synchronized (obj){
//            obj.notify();       //唤醒obj上一个线程
            obj.notifyAll();    //唤醒obj上所有等待线程
        }
    }

}
